<?xml version="1.0" encoding="UTF-8"?>
<html>
    <head>
        <link type="text/css" rel="stylesheet" href="./css/template.css" />
        <link type="text/css" rel="stylesheet" href="./css/SyntaxHighlighter.css" />
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>JavaBeans : Première approche</title>
        <script language="javascript" src="./js/shInit.js" />
        <script language="javascript" src="./js/shCore.js" />
        <script language="javascript" src="./js/shBrushCpp.js" />
        <script language="javascript" src="./js/shBrushCSharp.js" />
        <script language="javascript" src="./js/shBrushCss.js" />
        <script language="javascript" src="./js/shBrushDelphi.js" />
        <script language="javascript" src="./js/shBrushJava.js" />
        <script language="javascript" src="./js/shBrushJScript.js" />
        <script language="javascript" src="./js/shBrushPhp.js" />
        <script language="javascript" src="./js/shBrushPython.js" />
        <script language="javascript" src="./js/shBrushRuby.js" />
        <script language="javascript" src="./js/shBrushSql.js" />
        <script language="javascript" src="./js/shBrushVb.js" />
        <script language="javascript" src="./js/shBrushXml.js" />
        <keywords>java beans</keywords>
        <author>Cyril JOUI</author>
    </head>
    <body>
        <div class="chapter">
            <h2>I. Qu'est ce que les Java-Beans ?</h2>
            <p align="left">
                Les développeur cherche au maximum à construire des applications à composants c'est-à-dire créer des modules afin de les réutiliser et d'améliorer leur productivité, leur développement et la robustesse de leurs programmes. Java, grâce aux Java-Beans répond parfaitement à cette attente, de façon simple et efficace.
                <br />
                Plusieurs tentatives de gestion de composants avaient été développées par IBM ou OpenDoc d'Apple mais elles ont toutes été des échecs.
                <br />
                Nous utiliserons le programme "BeanBox" qui est un utilitaire de visualisation / test / debug de Beans, développé par Sun et téléchargeable sur leur site (
                <a href="http://www.java.sun.com" target="_blank">http://www.java.sun.com</a>
                ). Ce programme est écrit en java et se veut donc portable aussi bien sous Windows et que sous Unix/Linux. Nous expliquerons en détail son fonctionnement au moment voulu.
            </p>
            <p align="left">
                Les Java-Beans représentent en fait un Design Pattern particulier. Vous ne serez pas surpris de savoir que vous en avez surement déjà utilisés ... En effet les librairies awt ou encore mieux swing sont totalement basés sur ce concept. Cela n'est pas étonnant car ces librairies proposent des composants réutilisables et complètements personnalisables.
                <br />
                Cependant un Java-Beans n'est rien d'autre qu'une classe et donc un objet. C'est cette simplicité qui fait que les Beans se développe rapidement. Vous connaissez peut être le développement d'ActiveX (ocx), objet COM ... qui se révèle impossible à développer car l'étendu des connaissances à avoir avant de pouvoir l'utiliser correctement est trop importante, Java supprime tout ça !
            </p>
        </div>
        <div class="chapter">
            <h2>II. Utilisation de BeanBox</h2>
            <p align="left">Nous allons étudier l'utilisation de l'application d'aide au développement de Beans par Sun. Ci dessous une copie d'écran de la fenêtre principale de            l'application :</p>
            <p align="center">
                <img src="images/01.gif" width="686" height="983" />
            </p>
            <p align="left">L'application se compose de plusieurs fenêtres :</p>
            <p align="left">L'application se compose de plusieurs fenêtres :</p>
            <ul>
                <li>
                    <div align="left">Fenêtre principale avec le menu qui permet de contrôler les tests, importer vos beans ...</div>
                </li>
                <li>
                    <div align="left">Fenêtre toolbox qui récapitule l'ensemble des beans importés.</div>
                </li>
                <li>
                    <div align="left">Fenêtre de tracer de méthode (permet de tracer vos propres évènements)</div>
                </li>
                <li>
                    <div align="left">Fenêtre propriétés du composant sélectionné</div>
                </li>
                <li>
                    <div align="left">Console de sortie</div>
                </li>
            </ul>
            <p align="left">Voici le premier beans qui va nous permettre de tester les fonctionnalités de base de BeanBox :</p>
            <textarea name="code" class="java">import java.awt.Canvas;
				import java.awt.*;
				public class AfficheCouleur extends Canvas {
				private int rouge;
				private int vert;
				private int bleu;
				public AfficheCouleur() {
				}
				// surcharge de paint
				public void paint(Graphics g) {
				g.setColor(new Color(rouge, vert, bleu));
				g.fillRect(0, 0, getWidth(), getHeight());
				}
				// setters
				public void setRouge(int rouge) {
				this.rouge = rouge;
				}
				public void setVert(int vert) {
				this.vert = vert;
				}
				public void setBleu(int bleu) {
				this.bleu = bleu;
				}
				// getters
				public int getRouge() {
				return rouge;
				}
				public int getVert() {
				return vert;
				}
				public int getBleu() {
				return bleu;
				}
				}</textarea>
            <p align="left">
                Pour utiliser le bean, le plus pratique est de créer une archive .jar qui contiendra les .class de votre beans (ici AfficheCouleur.class).
                <br />
                ATTENTION : vous devez indiquer dans le manifest que votre jar est un Bean ! pour cela créer un fichier
                <strong>AfficheCouleur.mf</strong>
                ( mf pour manifest) :
            </p>
            <p align="left">
                Manifest-Version: 1.0
                <br />
                Name: AfficheCouleur.class
                <br />
                Java-Bean: True
            </p>
            <p align="left">
                Si votre class AfficheCouleur est dans un package vous devrez changer le "Name" en
                <strong>package.souspackage.AfficheCouleur</strong>
                (en changeant respectivant package.souspackage par l' arborescence de votre package).
                <br />
                Une fois le manifest créé, vous pouvez créer votre jar via la commande :
                <strong>jar cvfm AfficheCouleur.jar AfficheCouleur.mf AfficheCouleur.class.</strong>
                <br />
                <strong>
                    <br />
                </strong>
                Vous pouvez récupérer l'archive toute faite
                <a href="resources/AfficheCouleur.jar" target="_blank">ici</a>
                .
                <strong>
                    <br />
                    <br />
                </strong>
                Vous pouvez maintenant tester votre Beans avec BeanBox. Il vous suffit d'importer votre .jar via File -&gt; Loaded.jar. Une fois importé vous retrouver votre composant dans la fenêtre TooBox. Cliquez dessus et insérez le dans la zone d'édition de la fenêtre principale. Vous voyez alors apparaitre votre composant et les propriétés associées dans la fenêtre (cf. image ci-dessous)
            </p>
            <p align="center">
                <img src="images/02.gif" width="637" height="550" />
            </p>
            <p align="left">Vous pouvez remarquer que dans les propriétés vous avez : bleu, rouge et vert. Essayer de jouer sur les getters et les setters (supprimer les méthodes) de la classe AfficheCouleur et regarder le résultat dans BeanBox.</p>
            <p align="left">Vous avez également la possiblité d'ajouter plusieurs composants et de gérer des évènements entre eux (sans effectuer une seule ligne de code !) il vous suffit d'aller dans Edit -&gt; Events, choisir un évènement et finalement lié cet évènement à un autre composant (avec la souris !). BeanBox vous demandera alors quelle méthode appeler lorsque l'évènement sera lancé. Ceci est très pratique pour vérifier que votre gestion d'évènement marche correctement.</p>
            <p align="left">Vous allez mieux comprendre comment marche ces beans grâce à l'étude du design pattern associé.</p>
        </div>
        <div class="chapter">
            <h2>III. Explication du Design Pattern</h2>
            <p align="left">Un design pattern n'est rien d'autre qu'un modèle de programmation d'un concept. Nous allons donc détailler ici celui d'un Java-Beans.</p>
            <p align="left">
                La première chose à respecter est les "setters" et les "getters". En effet c'est grâce à ces méthodes publiques que l'on va pouvoir récupérer ou paramétrer une propriété du Bean. Dans notre exemple de l'afficheur de couleur, nous avons 3 propriétés qui sont rouge, vert et bleu (les composantes de la couleur affichée). Bien entendu nous avons mis ces membres en "private" afin que chaque modification soit faite via les setters.
                <br />
                Nos 3 propriétés sont en lecture/écriture car chaque membre a son propre getter et setter. Si nous omettons le setter setRouge par exemple, le membre rouge ne sera qu'en lecture seule (ceci peut parfois être pratique).
            </p>
            <p align="left">
                La seconde chose concerne les évènements.
                <br />
                Voici un petit rappel sur le concept des évènements en java.
                <br />
                La gestion d'évènements en java suit un design pattern précis. L' évènement est représenté par un objet. Le type d'évènement est décrit par une interface qui permettra d'être implémentée lors de la gestion de l'évènement dans un programme. Afin de respecter les conventions voici comment vous devez nommer vos classes :
            </p>
            <ul>
                <li>
                    <div align="left">XxxListener pour l'interface de votre évènement.</div>
                </li>
                <li>
                    <div align="left">XxxEvent pour l'objet qui décrira votre évènement.</div>
                </li>
            </ul>
            <p align="left">
                De plus, votre classe XxxListener doit hériter de EventListener et votre classe XxxEvent doit hériter de EventObject.
                <br />
                Par exemple si vous ajouter un événement s'appelant nouvelleHeure (par exemple pour une montre) vous devrez créer un prototype nouvelleHeure ( NouvelleHeureEvent nhe ) dans votre NouvelleHeureListener interface.
                <br />
                <br />
                Si vous souhaitez créer un nouveau type d'évènement dans votre composant vous devrez gérer l'ajout de listener et leur suppression. Afin de respecter les conventions, vous définirez les méthodes : addXxxListener (XxxListener xl) et removeXxxListener (XxxListener xl). Voici un schéma récapitulatif sur la gestion des évènements :
            </p>
            <p align="center">
                <img src="images/03.gif" width="494" height="373" />
            </p>
            <p align="left">Cependant il faut utiliser la création de nouveaux évènements avec parcimonie et bien vérifier que l'évènement n'existe pas déjà. Dans notre exemple de la montre il est préférable de passer par un PropertyChangeEvent. Pour cela vous utiliserez l'objet PropertyChangeSupport (qui contient principalement les méthodes addPropertyChangeListener et removePropertyChangeListener) qui vous aideront à gérer ces évènements.</p>
            <p align="left">Si l'on crée une instance PropertyChangeSupport pcs dans notre classe, nous pouvons utiliser pcs.firePropertyChange ( "nom_propriete", ancienneValeur, nouvelleValeur ) pour "lancer" l'évènement et donc appeler les différentes actions qui auront été préalablement ajoutées (via les addXxxListener et addXxxListener méthodes).</p>
        </div>
        <div class="chapter">
            <h2>IV. Exemple de beans</h2>
            <p align="left">Nous allons, afin de bien comprendre comment marche les beans, développer un sélecteur de couleur très simple. Voici à quoi nous allons arriver :</p>
            <p align="center">
                <img src="images/04.gif" width="400" height="551" />
            </p>
            <p align="left">Cette application se compose :</p>
            <ul>
                <li>
                    <div align="left">de trois scrollbares qui identifient les composantes rouge, vert et bleu (RVB).</div>
                </li>
                <li>
                    <div align="left">d'un évènement personnalisées qui indique que la couleur a changé (nous aurions cependant dû  faire cela via un PropertyChange). Il nous faudra donc créer nos classes et interfaces pour cet évènement.</div>
                </li>
            </ul>
            <p align="left">
                Voici le code globale que nous allons commenter par la suite :
                <textarea name="code" class="java">/* Classe principale du beans (interface graphique)
					*
					*/
					import java.awt.*;
					import javax.swing.*;
					import java.awt.event.*;
					import java.io.*;
					import java.beans.*;
					import java.util.*;
					public class ColorSelector extends JPanel implements AdjustmentListener, Serializable {
					private JScrollBar jscRouge = new JScrollBar(JScrollBar.HORIZONTAL);
					private JScrollBar jscVert = new JScrollBar(JScrollBar.HORIZONTAL);
					private JScrollBar jscBleu = new JScrollBar(JScrollBar.HORIZONTAL);
					private GridLayout gridLayout1 = new GridLayout(4, 1);
					// event
					private ArrayList tabChangedColorListeners = new ArrayList();
					public ColorSelector() {
					try {
					jbInit();
					} catch (Exception ex) {
					ex.printStackTrace();
					}
					}
					private void jbInit() throws Exception {
					// layout
					this.setLayout(gridLayout1);
					// parametre
					jscBleu.setMaximum(255);
					jscRouge.setMaximum(255);
					jscVert.setMaximum(255);
					// adding
					this.add(jscRouge, null);
					this.add(jscVert, null);
					this.add(jscBleu, null);
					// listeners
					jscBleu.addAdjustmentListener(this);
					jscRouge.addAdjustmentListener(this);
					jscVert.addAdjustmentListener(this);
					}
					/**
					* adjustmentValueChanged of scrollbars
					*
					* @param e AdjustmentEvent
					*/
					public void adjustmentValueChanged(AdjustmentEvent e) {
					// Nouvel objet nouvelle couleur
					Color newColor = new Color(jscRouge.getValue(), jscVert.getValue(), jscBleu.getValue());
					// Nouveau event
					fireChangedColor(getBackground(), newColor);
					// Change la couleur du fond
					setBackground(newColor);
					}
					// event ChangedColorListener
					public void addChangedColorListener(ChangedColorListener ccl) {
					tabChangedColorListeners.add(ccl);
					}
					public void removeChangedColorListener(ChangedColorListener ccl) {
					tabChangedColorListeners.remove(ccl);
					}
					public void fireChangedColor(Color oldColor, Color newColor) {
					ChangedColorEvent tmpEvent = new ChangedColorEvent(this, newColor);
					for (int i = 0; i
					&lt; tabChangedColorListeners.size(); i++) {
					((ChangedColorListener) tabChangedColorListeners.get(i)).changedColor(tmpEvent);
					}
					}
					// setters
					public void setColor(Color col) {
					jscRouge.setValue(col.getRed());
					jscVert.setValue(col.getGreen());
					jscBleu.setValue(col.getBlue());
					setBackground(col);
					}
					// getters
					public Color getColor() {
					return getBackground();
					}
					}</textarea>
                <textarea name="code" class="java">/* Objet évènement pour notre évènement personnalisé
					*
					*/
					import java.util.EventObject;
					import java.awt.*;
					public class ChangedColorEvent extends EventObject {
					private Color color;
					// Constructeur
					public ChangedColorEvent(Object source, Color col) {
					super(source);
					color = col;
					}
					// getter
					public Color getColor() {
					return this.color;
					}
					}</textarea>
                <textarea name="code" class="java">/* Interface pour l'évènement personnalisé
					*
					*/
					import java.util.EventListener;
					public interface ChangedColorListener extends EventListener {
					public void changedColor(ChangedColorEvent cce);
					}</textarea>
            </p>
            <p>
                Vous pouvez récupérer le code
                <a href="resources/ColorSelector-src.zip" target="_blank">ici</a>
                .
                <br />
                La classe ColorSelector est celle qui représente le composant graphiquement, on lui a ajouté 3 scrollbares et on utilise le gridLayout pour les placer. Notez que nous avons nos 3 méthodes et un ArrayList:
            </p>
            <ul>
                <li>addChangedColorListener(ChangedColorListener ccl)</li>
                <li>removeChangedColorListener(ChangedColorListener ccl)</li>
                <li>fireChangedColor (Color oldColor, Color newColor)</li>
                <li>ArrayList tabChangedColorListeners</li>
            </ul>
            <p>qui servent à la gestion de notre évènement personnalisé (fireChangedColorListener est optionnelle mais elle permet de mieux structuré le code, ce que l'on cherche par l'utilisation de design pattern). Le membre : tabChangedColorListeners permet de stocker les différentes actions à effectuer lorsque la couleur change (c'est la méthode fireChangedColor qui permettra d'effectuer cette tâche).</p>
            <p>La classe ChangedColorEvent représente l'objet évènement qui est utilisé pour décrire notre évènement de changement de couleur. La méthode getColor permet de récupérer la nouvelle couleur.</p>
            <p>L'interface ChangedColorListener représente les différentes actions disponibles pour cette évènements (via les prototypes des méthodes qu'il faudra implémenter lors de l'utilisation). Ici nous en avons qu'une seule : changedColor.</p>
            <p>Comme vous pouvez le voir la création de Java Beans est vraiment très simple. Nous allons maintenant voir comment intégrer notre beans dans une application concrète.</p>
        </div>
        <div class="chapter">
            <h2>V. Intégration d'un JavaBeans dans une application</h2>
            <p>
                Nous allons tout simplement utilisez le Java Beans crée au IV et l'intégrer dans une Frame. Un Java Beans est un composant comme un autre, il vous suffit donc de l'utiliser comme un JLabel. Voici le code qui nous permet de tester notre sélecteur de couleur.
                <br />
                <br />
                <textarea name="code" class="java">import javax.swing.JFrame;
					import java.awt.HeadlessException;
					// Import de notre Java Beans à ne pas oublier
					import com.labosun.cj.javabeans.colorselector.*;
					import javax.swing.*;
					import java.awt.*;
					public class ColorSelectorFrameTest extends JFrame {
					ColorSelector cs;
					JLabel lblTest;
					public ColorSelectorFrameTest() throws HeadlessException {
					// Inits
					cs = new ColorSelector();
					lblTest = new JLabel("Couleur");
					// Quitte l'application quand on ferme
					this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
					this.setSize(100, 300);
					this.getContentPane().setLayout(new BorderLayout());
					// add
					this.getContentPane().add(cs, BorderLayout.CENTER);
					this.getContentPane().add(lblTest, BorderLayout.SOUTH);
					// Listener
					cs.addChangedColorListener(new ChangedColorListener() {
					/**
					* changedColor
					*
					* @param cce ChangedColorEvent
					*/
					public void changedColor(ChangedColorEvent cce) {
					lblTest.setText(cce.getColor().toString());
					}
					});
					}
					// main
					public static void main(String[] args) {
					new ColorSelectorFrameTest().show();
					}
					}</textarea>
            </p>
            <div align="left" class="subChapter">
                <p>
                    Vous pouvez remarquer que nous n'avons pas de particularités dans le code, nous utilisons notre sélecteur de couleur comme un JLabel ou un JButton (ajout de listeners, paramétrage du composant)... Vous pourrez trouver le code source
                    <a href="resources/ColorSelectorFrameTest.java" target="_blank">ici</a>
                    et le jar executable de l'application
                    <a href="resources/TesteurColorSelector.jar" target="_blank">ici</a>
                    .
                </p>
                <div />
                <div class="chapter">
                    <h2>Conclusion</h2>
                    <p>
                        Nous avons vu les bases de la création de Java Beans. Vous avez pu remarquer comme il est simple de créer ses propres composants. Les Beans sont très intégrés dans java car ils sont faciles d'emploi, de création et très modulable. Maintenant que vous savez les créer vous pourrez également développer des interfaces pour les personnaliser (nous avons vu que BeanBox en génère à la volée pour chaque composant ... bien entendu nous pouvons générer nos propres interfaces de personnalisation (via l'interface Customizer) pour aller plus loin :
                        <a href="http://java.sun.com/products/javabeans/" target="_blank">
                            http://java.sun.com/products/javabeans/.
                            <br />
                        </a>
                    </p>
                </div>
            </div>
        </div>
    </body>
</html>

